from PySide6.QtCore import Qt, Slot
from PySide6.QtWidgets import QMdiSubWindow, QMessageBox
from PySide6.QtGui import QIcon

from Forms.LogWindow import LogWindow
from Forms.SendCommandWindow import SendCommandWindow
from Forms.MessagesWindow import MessagesWindow
from Forms.HttpServerWindow import HttpServerWindow

from Communicate.UdpClient import UdpClient
from Communicate.TcpClient import TcpClient
from Communicate.TcpServer import TcpServer

from Components.MessageBoxFunc import MessageBoxFunc

from Funcs.Config import Config

class DeviceWindow(QMdiSubWindow):
    def __init__(self, supportDevice, parent = None):
        super().__init__(parent)

        #protected
        self._OriginalTitle = supportDevice.deviceDisplayName
       
        self._DeviceIP = ""
        
        self._OtaUrl = ""
        self._SupportDevice = supportDevice
        self._OtaStarted = ""

        self._LogWindow = LogWindow()
        self._SendCommandWindow = SendCommandWindow()
        self._MessagesWindow = MessagesWindow()
        self._HttpServerWindow = HttpServerWindow()

        #private
        self.__ui = None
        self.__CmdClient = UdpClient(supportDevice.deviceEncrypt)
        self.__LogClient = TcpClient()
        self.__LogServer = TcpServer()
        self.__IsClosed = False
        self.__CmdPort = 0
        self.__LogPort = 0

        self.setAttribute(Qt.WA_DeleteOnClose)

        self.setWindowTitle(self._OriginalTitle)
        
        #隐藏标题栏（无边框）
        flags = self.windowFlags()
        self.setWindowFlags(flags | Qt.FramelessWindowHint)
        self.setFixedSize(1000, 877)

        if 0 == len(supportDevice.deviceIcon):
            self.setWindowIcon(QIcon(":/Device.png"))
        else:
            iconPath = Config.GetCurrentPath() + "/icon/" + supportDevice.deviceIcon
            self.setWindowIcon(QIcon(iconPath))

        self.__CmdClient.DateReceived.connect(self.on_CmdDateReceived)

        self.__LogClient.Connected.connect(self.on_Connected)
        self.__LogClient.DisConnected.connect(self.on_DisConnected)
        self.__LogClient.DateReceived.connect(self.on_LogDateReceived)

        self.__LogServer.Connected.connect(self.on_Connected)
        self.__LogServer.DisConnected.connect(self.on_DisConnected)
        self.__LogServer.DateReceived.connect(self.on_LogDateReceived)

        self._SendCommandWindow.SendCommandTriggerd.connect(self.SendCommandText)

        self._HttpServerWindow.HttpStarted.connect(self.on_HttpStarted)
        self._HttpServerWindow.HttpStopped.connect(self.on_HttpStopped)

    def __del__(self):
        try:
            del self._HttpServerWindow
            self._HttpServerWindow = None
        except:
            pass

    def SetupUi(self, ui):
        self.__ui = ui

    def GetDeviceIP(self):
        return self._DeviceIP

    def Connected(self, ip, port):
        pass

    def DisConnected(self):
        pass

    def CmdDateReceived(self, data):
        pass

    def LogDateReceived(self, data):
        pass

    def HttpStarted(self):
        pass

    def HttpStopped(self):
        pass

    def Init(self, ip):
        iplist = ip.split('.')
        if 4 == len(iplist) and iplist[3].isdigit():           
            self._DeviceIP = ip

            self.__LogServer.Start(self.__CmdClient.GetSocketPort() + 1)
            self._LogWindow.SetDeviceIP(ip)
            self._SendCommandWindow.SetDeviceIP(ip)
            self._MessagesWindow.SetDeviceIP(ip)
        
            self._HttpServerWindow.SetWindowPort(int(iplist[3]))

            self._SendCommandWindow.SetDeviceName(self._SupportDevice.deviceDisplayName)
            self._HttpServerWindow.SetDeviceName(self._SupportDevice.deviceDisplayName)
            
            return True
        else:
            return False

    def Connect(self, cmdPort, logPort):
        self.setWindowTitle(self._OriginalTitle + ":" + self._DeviceIP + "未连接")

        self.__CmdPort = cmdPort
        self.__LogPort = logPort

        self.__LogClient.DisConnect()
        self.__LogServer.DisConnect()

        self.__CmdClient.Connect(self._DeviceIP, cmdPort)
        self.__LogClient.Connect(self._DeviceIP, logPort)
        
    def VerifyConnect(self, cmdPort, logPort):
        self.setWindowTitle(self._OriginalTitle + ":" + self._DeviceIP + "未连接")

        self.__CmdPort = cmdPort
        self.__LogPort = logPort

        self.__LogClient.DisConnect()

        self.__CmdClient.Connect(self._DeviceIP, cmdPort)
    
    def LogConnect(self, cmdPort, logPort):
        self.setWindowTitle(self._OriginalTitle + ":" + self._DeviceIP + "未连接")

        self.__CmdPort = cmdPort
        self.__LogPort = logPort

        self.__LogClient.DisConnect()

        self.__LogClient.Connect(self._DeviceIP, logPort)

    def ReConnect(self):
        if not self._SupportDevice.deviceEncrypt:
            self.__LogClient.DisConnect()
            self.__LogServer.DisConnect()
            
            self.__CmdClient.Connect(self._DeviceIP, self.__CmdPort)
            self.__LogClient.Connect(self._DeviceIP, self.__LogPort)
        else:
            self.__LogClient.DisConnect()
            self.VerifyConnect(self.__CmdPort, self.__LogPort)

    def on_Connected(self, ip, port):
        self.setWindowTitle(self._OriginalTitle + ":" + ip + "已连接")
        self._LogWindow.SetDeviceIP(ip)
        self._SendCommandWindow.SetDeviceIP(ip)
        self._MessagesWindow.SetDeviceIP(ip)
        self.Connected(ip, port)

    def on_DisConnected(self):
        self.setWindowTitle(self._OriginalTitle + ":" + self._DeviceIP + "未连接")

        if not self.__IsClosed:
            if (not self._LogWindow is None):
                self._LogWindow.SetDeviceIP("")

            if (not self._LogWindow is None):
                self._SendCommandWindow.SetDeviceIP("")

            if (not self._LogWindow is None):
                self._MessagesWindow.SetDeviceIP("")

            self.DisConnected()

    def on_CmdDateReceived(self, data, ip, port):
        self._MessagesWindow.AddReceivedMsg(ip + ":" + data)
        self.CmdDateReceived(data)

    def on_LogDateReceived(self, data):
        self._LogWindow.AddLog(data)
        self.LogDateReceived(data)

    def on_HttpStarted(self):
        self.__ui.pushButton_Http.setIcon(QIcon(":/http.png"))
        self.HttpStarted()

    def on_HttpStopped(self):
        self.__ui.pushButton_Http.setIcon(QIcon(":/http_stopped.png"))
        self.HttpStopped()

    @Slot()
    def on_pushButton_Log_clicked(self):
        self._LogWindow.showNormal()
        self._LogWindow.activateWindow()
        
    @Slot()
    def on_pushButton_SendCmd_clicked(self):
        self._SendCommandWindow.showNormal()
        self._SendCommandWindow.activateWindow()
        
    @Slot()
    def on_pushButton_Messages_clicked(self):
        self._MessagesWindow.showNormal()
        self._MessagesWindow.activateWindow()
        
    @Slot()
    def on_pushButton_Http_clicked(self):
        self._HttpServerWindow.showNormal()
        self._HttpServerWindow.activateWindow()

    def closeEvent(self, event):
        try:
            self.__IsClosed = True
            self._HttpServerWindow.close()
            self.__LogClient.DisConnect()
            self.__LogServer.DisConnect()
        except:
            pass

    def SendCommandText(self, command):
        if self.__CmdClient.SendData(command):
            self._MessagesWindow.AddSentMsg(self.__CmdClient.GetIP() + ":" + command)

    def ShowMessageBox(self, title, content, icon = QMessageBox.Icon.Information):
        MessageBoxFunc.ShowMessageBox(title, self._OriginalTitle + self._DeviceIP + content, self, icon)
